﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using AutoPartsSearch.Web.ViewModels;
using System.Text;

namespace AutoPartsSearch.Web.HtmlHelpers
{
    public static class PagingHelper
    {
        public static int MaximumItems = 10;

        public static MvcHtmlString PageLinks(this HtmlHelper helper, PagingInfo pagingInfo, Func<int, string> pageUrl, string classes = null, string selectedClass = "selected")
        {
            StringBuilder sb = new StringBuilder();
            if (pagingInfo.TotalPages == 1)
            {
                return MvcHtmlString.Create(string.Empty);
            }

            var pagingBounds = new PagingBounds(pagingInfo, MaximumItems);
            if (pagingBounds.NeedToGenerateBackLink)
            {
                sb.Append(GetBackLink(pageUrl, classes, pagingBounds.MinBound));
            }

            for (int i = pagingBounds.MinBound; i <= pagingBounds.MaxBound; i++)
            {
                TagBuilder tagBuilder = GetTag(i.ToString(), pageUrl(i), classes);
                if (i == pagingInfo.CurrentPage)
                {
                    tagBuilder.AddCssClass(selectedClass);
                }
                sb.Append(tagBuilder.ToString());
            }
            if (pagingBounds.NeedToGenerateForwardLink)
            {
                sb.Append(GetForwardLink(pageUrl, classes, pagingBounds.MaxBound));
            }
            return MvcHtmlString.Create(sb.ToString());
        }


        private static string GetBackLink(Func<int, string> pageUrl, string classes, int minBound)
        {
            return GetTag("<<", pageUrl(minBound - 1), classes).ToString();
        }

        private static string GetForwardLink(Func<int, string> pageUrl, string classes, int maxBound)
        {
            return GetTag(">>", pageUrl(maxBound + 1), classes).ToString();
        }

        private static TagBuilder GetTag(string text, string url, string classes)
        {
            TagBuilder tagBuilder = new TagBuilder("a");
            tagBuilder.MergeAttribute("href", url);
            tagBuilder.InnerHtml = text;
            if (!string.IsNullOrEmpty(classes))
            {
                tagBuilder.AddCssClass(classes);
            }
            return tagBuilder;
        }
    }

    internal class PagingBounds
    {
        private readonly PagingInfo _pagingInfo;
        private readonly int _visiblePageCount;
        private readonly int _currentPagingGroup;

        public int MinBound
        {
            get
            {
                return (_currentPagingGroup * _visiblePageCount) - _visiblePageCount + 1;
            }
        }

        public int MaxBound
        {
            get
            {
                var maxBound = _currentPagingGroup * _visiblePageCount;
                if (maxBound > _pagingInfo.TotalPages)
                {
                    maxBound = _pagingInfo.TotalPages;
                }
                return maxBound;
            }
        }

        public bool NeedToGenerateBackLink
        {
            get
            {
                return _currentPagingGroup > 1;
            }
        }

        public bool NeedToGenerateForwardLink
        {
            get
            {
                return _pagingInfo.TotalPages > MaxBound;
            }
        }

        public PagingBounds(PagingInfo pagingInfo, int visiblePageCount)
        {
            _pagingInfo = pagingInfo;
            _visiblePageCount = visiblePageCount;
            _currentPagingGroup = (int)(Math.Ceiling((decimal)pagingInfo.CurrentPage / visiblePageCount));
        }
    }
}